#include <stdio.h>
#include <string.h>
// #include "util.h"
// #include <alloca.h>

#define MGMT_SCU_REG_BASE     0xd0010000

#include "./pcie_src/pcie_rc_reg_access.c"

int pcie_test()
{
  uint32_t pcie_rdata;
  uint32_t pcie_wdata;
  //pcie clock and rest initial
  //{{{
  //aux clock en
  reg32_read(MGMT_SCU_REG_BASE + 0x058, pcie_rdata);
  reg32_write(MGMT_SCU_REG_BASE + 0x058, pcie_rdata | (0x1 << 1));

  //pcie hs pll cfg
  //{{{
  reg32_read(MGMT_SCU_REG_BASE + 0x018, pcie_rdata);
  reg32_write(MGMT_SCU_REG_BASE + 0x018, pcie_rdata | 
    (1 << 24)   | //mcpu.pll_postdiv1
    (0 << 21)   | //mcpu.pll_postdiv2
    (1 << 15)   | //mcpu.pll_refdiv
    (20 << 3)   | //mcpu.pll_fbdiv
    (0x1 << 2)  | //mcpu.pll_fout4phaseen
    (0x1 << 1)  | //mcpu.pll_fouten
     0x1); //mcpu.pll_foutpostdiven

  //pll en and change
  reg32_read(MGMT_SCU_REG_BASE + 0x028, pcie_rdata);
  reg32_write(MGMT_SCU_REG_BASE + 0x028, pcie_rdata | (0x1 << 8) | 0x1);

  //wait pll lock
  pcie_rdata = 0;
  while(1) {
    reg32_read(MGMT_SCU_REG_BASE + 0x064, pcie_rdata);
    printf("pice hs_pll_status = 0x%08x\r\n", pcie_rdata);
    if ((pcie_rdata & 1) != 0) {
      printf("pcie hs pll locked\r\n");
      break;
    }
  }
  //}}}

  //pcie axim axis de-reset
  reg32_read(MGMT_SCU_REG_BASE + 0x000, pcie_rdata);
  reg32_write(MGMT_SCU_REG_BASE + 0x000, pcie_rdata | (0x1 << 15));
  //}}}

  dut_pcie_phy_ini(1);
  reg32_read_write_check_rw(CNCR_BASE + ADDR_CTRL_0 + 0x04/*CTRL0*/);
  reg32_read_write_check_rw(PNCR_BASE + ADDR_CTRL_0 + 0x04/*CTRL0*/);
  reg32_read_write_check_rw(CTRL_BASE+0x00000814 /*PORT_LOGIC.PHY_CONTROL_OFF*/);
  reg32_read_write_check_rw(PHY_BASE+ 0x0b * 4 /*SUP_DIG_MPLLA_BW_HIGH_OVRD_IN*/);
  reg32_read_write_check_rw(PHY_BASE+ 0x00040000 + 0x0b * 4 /*SUP_DIG_MPLLA_BW_HIGH_OVRD_IN*/);

  return 0;
}

